package com.ttdevs.ttrss.db;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.ttdevs.ttrss.bean.Article;
import com.ttdevs.ttrss.bean.Source;
import com.ttdevs.ttrss.db.DBHelper.TableArticle;
import com.ttdevs.ttrss.db.DBHelper.TableGroup;
import com.ttdevs.ttrss.db.DBHelper.TableSource;

public class DBManager implements IDBManager {
	private static IDBManager dbm;
	private static SQLiteDatabase db;

	private DBManager(Context context) {
		db = new DBHelper(context).getWritableDatabase();
	}

	public static IDBManager getInstance(Context context) {
		if (dbm == null) {
			dbm = new DBManager(context);
		}
		return dbm;
	}

	@Override
	public boolean createGroup(String name, String orderKey) {
		String selection = TableGroup.NAME + " = ? ";
		String[] selectionArgs = new String[] { name };
		Cursor cursor = db.query(TableGroup.TABLE_NAME, null, selection, selectionArgs, null, null, null);
		int count = cursor.getCount();
		cursor.close();
		if (count > 0) {
			return false;
		}

		ContentValues cv = new ContentValues();
		cv.put(TableGroup.NAME, name);
		cv.put(TableGroup.ORDER, orderKey);

		long newRowId = db.insert(TableGroup.TABLE_NAME, null, cv);

		return newRowId > 0;
	}

	@Override
	public boolean deleteGroup(String name) {
		boolean isSuccess = false;
		db.beginTransaction();
		try {
			// first update group
			ContentValues cv = new ContentValues();
			cv.put(TableSource.GROUP, "");
			String whereClause = TableSource.GROUP + " = ? ";
			String[] whereArgs = new String[] { name };
			db.update(TableSource.TABLE_NAME, cv, whereClause, whereArgs);

			// second delete group
			whereClause = TableGroup.NAME + " = ? ";
			db.delete(TableGroup.TABLE_NAME, whereClause, whereArgs);

			db.setTransactionSuccessful();
			isSuccess = true;
		} catch (Exception e) {
			isSuccess = false;
		} finally {
			db.endTransaction();
		}
		return isSuccess;
	}

	@Override
	public boolean editGroup(String oldName, String newName) {
		ContentValues cv = new ContentValues();
		cv.put(TableGroup.NAME, newName);
		String whereClause = TableGroup.NAME + " = ? ";
		String[] whereArgs = new String[] { oldName };

		return db.update(TableGroup.TABLE_NAME, cv, whereClause, whereArgs) > 0;
	}

	@Override
	public List<String> queryAllGroup() {
		String orderBy = TableGroup.ORDER + " asc ";
		Cursor cursor = db.query(TableGroup.TABLE_NAME, null, null, null, null, null, orderBy);
		List<String> list = new LinkedList<String>();
		while (cursor.moveToNext()) {
			list.add(cursor.getString(cursor.getColumnIndex(TableGroup.NAME)));
		}
		cursor.close();
		return list;
	}

	@Override
	public boolean addSource(Source src) {
		ContentValues cv = new ContentValues();
		cv.put(TableSource.TITLE, src.getTitle());
		cv.put(TableSource.LINK, src.getLink());
		cv.put(TableSource.DESCRIPTION, src.getDescription());
		cv.put(TableSource.ICON, src.getIcon());
		cv.put(TableSource.SRCIDQQ, src.getSourceid());
		cv.put(TableSource.GROUP, src.getBelonggroup());
		cv.put(TableSource.LASTBUILDDATE, src.getLastbuilddate());
		cv.put(TableSource.WIFIAUTOUPDATE, src.isWifiautoupdate());
		cv.put(TableSource.FREQUENCY, src.getFrequency());
		cv.put(TableSource.ORDER, src.getOrderkey());
		cv.put(TableSource.CREATETIME, System.currentTimeMillis());

		return db.insert(TableSource.TABLE_NAME, null, cv) != -1;
	}

	@Override
	public boolean editSource(Source src) {
		ContentValues cv = new ContentValues();
		if (src.getTitle() != null) {
			cv.put(TableSource.TITLE, src.getTitle());
		}
		if (src.getDescription() != null) {
			cv.put(TableSource.DESCRIPTION, src.getDescription());
		}
		if (src.getIcon() != null) {
			cv.put(TableSource.ICON, src.getIcon());
		}
		if (src.getSourceid() != null) {
			cv.put(TableSource.SRCIDQQ, src.getSourceid());
		}
		if (src.getBelonggroup() != null) {
			cv.put(TableSource.GROUP, src.getBelonggroup());
		}
		if (src.getLastbuilddate() != 0) {
			cv.put(TableSource.LASTBUILDDATE, src.getLastbuilddate());
		}
		cv.put(TableSource.WIFIAUTOUPDATE, src.isWifiautoupdate() ? 1 : 0);
		if (src.getFrequency() != 0) {
			cv.put(TableSource.FREQUENCY, src.getFrequency());
		}
		if (src.getOrderkey() != null) {
			cv.put(TableSource.ORDER, src.getOrderkey());
		}

		String whereClause = TableSource.LINK + " = ? ";
		String[] whereArgs = new String[] { src.getLink() };

		return db.update(TableSource.TABLE_NAME, cv, whereClause, whereArgs) > 0;
	}

	@Override
	public boolean deleteSource(String link) {
		boolean isSuccess = false;
		db.beginTransaction();
		try {
			// first delete articles from article table
			String whereClause = TableArticle.LINK + " = ? ";
			String[] whereArgs = new String[] { link };
			db.delete(TableArticle.TABLE_NAME, whereClause, whereArgs);

			// second delete source
			whereClause = TableSource.LINK + " = ? ";
			whereArgs = new String[] { link };
			db.delete(TableGroup.TABLE_NAME, whereClause, whereArgs);

			db.setTransactionSuccessful();
			isSuccess = true;
		} catch (Exception e) {
			isSuccess = false;
		} finally {
			db.endTransaction();
		}
		return isSuccess;
	}

	@Override
	public List<Source> querySource(String group) {
		String orderBy = TableSource.ORDER + " asc ";
		String selection = TableSource.GROUP + " = ? ";
		String[] selectionArgs = new String[] { group };
		Cursor cursor = db.query(TableSource.TABLE_NAME, null, selection, selectionArgs, null, null, orderBy);
		if (cursor.getCount() <= 0) {
			return null;
		}
		List<Source> list = new ArrayList<Source>();
		while (cursor.moveToNext()) {
			Source src = new Source();
			// private String title;
			// private String link;
			// private String description;
			// private String icon;
			// private String sourceid;
			// private String belonggroup;
			// private long lastbuilddate;
			// private boolean wifiautoupdate;
			// private int frequency;
			// private String orderkey;
			// private long createTime;
			src.setTitle(cursor.getString(cursor.getColumnIndex(TableSource.TITLE)));
			src.setLink(cursor.getString(cursor.getColumnIndex(TableSource.LINK)));
			src.setDescription(cursor.getString(cursor.getColumnIndex(TableSource.DESCRIPTION)));
			src.setIcon(cursor.getString(cursor.getColumnIndex(TableSource.ICON)));
			list.add(src);
		}
		cursor.close();
		return list;
	}

	@Override
	public boolean insertArticles(List<Article> articles) {
		String source = "";
		boolean isSuccess = false;
		db.beginTransaction();
		try {
			// first insert article
			ContentValues cv = new ContentValues();
			for (Article article : articles) {
				cv.clear();
				cv.put(TableArticle.TITLE, article.getTitle());
				cv.put(TableArticle.LINK, article.getLink());
				cv.put(TableArticle.ICON, article.getIcon());
				cv.put(TableArticle.DESC, article.getDescription());
				cv.put(TableArticle.AUTHOR, article.getAuthor());
				cv.put(TableArticle.PUBDATE, article.getPubDate());
				cv.put(TableArticle.GUID, article.getGuid());
				cv.put(TableArticle.SOURCE, article.getSource());
				cv.put(TableArticle.MARK, 0); // 0未标记，1标记
				cv.put(TableArticle.READ, 0); // 0未读，1已读
				cv.put(TableArticle.CREATETIME, System.currentTimeMillis());

				db.insert(TableArticle.TABLE_NAME, null, cv);
				source = article.getSource();
			}
			// second update source
			cv.clear();
			cv.put(TableSource.LASTBUILDDATE, System.currentTimeMillis());
			String whereClause = TableSource.LINK + " = ? ";
			String[] whereArgs = new String[] { source };
			db.update(TableSource.TABLE_NAME, cv, whereClause, whereArgs);

			db.setTransactionSuccessful();
			isSuccess = true;
		} catch (Exception e) {
			isSuccess = false;
		} finally {
			db.endTransaction();
		}
		return isSuccess;
	}

	@Override
	public boolean markArticle(int articleID, boolean isMark) {
		ContentValues cv = new ContentValues();
		cv.put(TableArticle.MARK, isMark ? 1 : 0);
		String whereClause = TableArticle._ID + " = ? ";
		String[] whereArgs = new String[] { String.valueOf(articleID) };
		db.update(TableArticle.TABLE_NAME, cv, whereClause, whereArgs);
		return false;
	}

	@Override
	public boolean markArticleRead(int articleID, boolean isRead) {
		ContentValues cv = new ContentValues();
		cv.put(TableArticle.READ, isRead ? 1 : 0);
		String whereClause = TableArticle._ID + " = ? ";
		String[] whereArgs = new String[] { String.valueOf(articleID) };
		db.update(TableArticle.TABLE_NAME, cv, whereClause, whereArgs);
		return false;
	}

	@Override
	public boolean deleteArticles(String url) {
		String whereClause = TableArticle.LINK + " = ? ";
		String[] whereArgs = new String[] { url };
		db.delete(TableArticle.TABLE_NAME, whereClause, whereArgs);
		return false;
	}

	@Override
	public List<Article> queryArticle(String source, int articleID, int pageSize) {
		List<Article> list = new ArrayList<Article>();
		
		String selection = TableArticle.SOURCE + " = ? ";
		String[] selectionArgs = new String[] { source };
		Cursor cursor = db.query(TableArticle.TABLE_NAME, null, selection, selectionArgs, null, null, null);
		
		if (cursor.getCount() <= 0) {
			return list;
		}
		
		while (cursor.moveToNext()) {
			Article article = new Article();
			article.setTitle(cursor.getString(cursor.getColumnIndex(TableArticle.TITLE)));
			list.add(article);
		}
		
		return list;
	}
}
